package modelo.bd.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import modelo.bd.ConexionPool;
import modelo.bd.excepcion.DAOException;
import modelo.dominio.Solicitud;
import modelo.servicio.CargarSolicitado;
import modelo.servicio.Flujos;
import modelo.servicio.Usuarios;

public class SolicitudDAO {

    private String query;

    public String procesar(String claveFlujo, long folio, String clavePaso,
            String claveEvento, double monto, String usuario,
            String comentarios, String claveCausa) throws DAOException {
        Connection conexion = null;
        CallableStatement sentencia = null;
        String error, salida;
        try {
            query = ("{CALL SIL_P_MANEJO_FLUJO(?,?,?,?,?,?,?,?,?,?,?)}");
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareCall(query);
            sentencia.setString(1, claveFlujo);
            sentencia.setLong(2, folio);
            sentencia.registerOutParameter(2, Types.DECIMAL);
            sentencia.setString(3, clavePaso);
            sentencia.setString(4, claveEvento);
            sentencia.setTimestamp(5, new java.sql.Timestamp(new Date().getTime()));
            sentencia.setDouble(6, monto);
            sentencia.setString(7, usuario);
            sentencia.setString(8, comentarios);
            sentencia.setString(9, claveCausa);
            sentencia.setString(10, "llave");
            sentencia.registerOutParameter(11, Types.VARCHAR);
            sentencia.execute();
            error = sentencia.getString(11);
            if (error == null) {
                salida = sentencia.getString(2);
            } else {
                salida = "Re: " + error;
            }
        } catch (SQLException ex) {
            throw new DAOException("Error SODP-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error SODP-SQL " + ex.getMessage());
            }
        }
        return salida;
    }

    public void add(Solicitud entity, String usuario) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            query = "INSERT INTO sil_historico_flujo (hifl_fluj_clave, hifl_numero, hifl_pafl_clave, \n"
                    + "                hifl_fecha, hifl_monto_flujo, hifl_usuario_creo, hifl_fecha_creo) \n"
                    + "VALUES('" + entity.getFlujo().getClave() + "', "
                    + " 0, '"
                    + entity.getClave() + "', '"
                    + entity.getFechaSolicitud() + "', "
                    + entity.getMontoSolicitud() + ", '"
                    + usuario + "', SYSDATE)";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error SODA-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error SODA-SQL " + ex.getMessage());
            }
        }
    }

    public void update(Solicitud entity, String usuario) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            query = ("UPDATE sil_historico_flujo \n"
                    //                        + "SET    repf_forzoso       = '" + entity.getForsozo()+ "', \n"
                    + "       repf_usuario_modif = '" + usuario + "', \n"
                    + "       repf_fecha_modif   = SYSDATE \n"
                    //+ ",       repf_uspe_clave    = '" + entity.getResponsable().getLogin() + "' \n"
                    + "WHERE  hifl_numero     = " + entity.getFolio() + " \n"
                    + "AND    hifl_fluj_clave = '" + entity.getClave() + "'");
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error SODU-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error SODU-SQL " + ex.getMessage());
            }
        }
    }

    protected List<Solicitud> select() throws DAOException {
        return null;
    }

    protected List<Solicitud> select(int numObj) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        ResultSet resultado = null;
        List<Solicitud> resultados = null;
        try {
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            resultado = sentencia.executeQuery();
            resultados = new ArrayList<Solicitud>();
            while (resultado.next()) {
                Solicitud solicitud = new Solicitud();
                solicitud.setFlujo(Flujos.instancia().porClave(resultado.getString("flujo_clave")));
                solicitud.setFolio(resultado.getLong("flujo_folio"));
                solicitud.setClave(resultado.getString("paso_clave"));
                solicitud.setDescripcion(resultado.getString("paso_descripcion"));
                solicitud.setDescripcionCorta(resultado.getString("paso_descripcion_corta") == null
                        ? "" : resultado.getString("paso_descripcion_corta"));
                solicitud.setAvisable(resultado.getString("paso_avisable").equalsIgnoreCase("S"));
                solicitud.setTipoPaso(resultado.getString("paso_tipo"));
                solicitud.setMontoAprobacion(resultado.getDouble("paso_monto"));

                solicitud.setFechaSolicitud(resultado.getTimestamp("fecha_solicitud"));
                solicitud.setMontoSolicitud(resultado.getDouble("monto_solicitud"));
                solicitud.setTerminado(resultado.getString("terminado").equalsIgnoreCase("S"));
                solicitud.setSolicitante(Usuarios.instancia().porClave(resultado.getString("solicitante_clave")));

                String llavePrimaria[] = new String[5];
                llavePrimaria[0] = resultado.getString("flujo_clave");
                llavePrimaria[1] = resultado.getString("flujo_folio");
                llavePrimaria[2] = resultado.getString("PK_1");
                llavePrimaria[3] = resultado.getString("PK_2");
                llavePrimaria[4] = resultado.getString("PK_3");
                solicitud.setSolictado(CargarSolicitado.generar(numObj, llavePrimaria));
                resultados.add(solicitud);
            }
        } catch (SQLException ex) {
            throw new DAOException("Error SODS-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error SODS-SQL " + ex.getMessage());
            }
        }
        return resultados;
    }

    public List<Solicitud> selectAll() throws DAOException {
        return select();
    }

    public List<Solicitud> selectWhere(String condition) throws DAOException {
        return select();
    }

    public List<Solicitud> selectFacturas(String condicion) throws DAOException {
        query = "SELECT hifl_fluj_clave            AS flujo_clave, \n"
                + "       hifl_numero                AS flujo_folio, \n"
                + "       hifl_fecha                 AS fecha_solicitud, \n"
                + "       hifl_monto_flujo           AS monto_solicitud, \n"
                + "       hifl_terminado             AS terminado,\n"
                + "       pfl1.pafl_clave            AS paso_clave, \n"
                + "       pfl1.pafl_descripcion      AS paso_descripcion, \n"
                + "       pfl1.pafl_desc_corta       AS paso_descripcion_corta, \n"
                + "       pfl1.pafl_tipo_paso        AS paso_tipo, \n"
                + "       pfl1.pafl_aviso            AS paso_avisable, \n"
                + "       pfl1.pafl_monto_aprobacion AS paso_monto,\n"
                + "       dehf_uspe_clave            AS solicitante_clave, \n"
                + "       fapr_numero                AS pk_1, \n"
                + "       fapr_prpo_numero           AS pk_2,\n"
                + "       'dummy'                    AS pk_3\n"
                + "FROM   sil_historico_flujo, \n"
                + "       sil_pasos_flujo pfl1, \n"
                + "       sil_detalle_historico_flujo, \n"
                + "       sil_pasos_flujo pafl2, \n"
                + "       sil_facturas_proveedor\n"
                + "WHERE  pfl1.pafl_fluj_clave  = hifl_fluj_clave \n"
                + "AND    pfl1.pafl_clave       = hifl_pafl_clave \n"
                + "AND    dehf_fluj_clave       = hifl_fluj_clave \n"
                + "AND    dehf_hifl_numero      = hifl_numero \n"
                + "AND    dehf_instancia        = 1 \n"
                + "AND    pafl2.pafl_fluj_clave = dehf_fluj_clave \n"
                + "AND    pafl2.pafl_clave      = dehf_pafl_clave \n"
                + "AND    pafl2.pafl_tipo_paso  = 'I' \n"
                + "AND    fapr_fluj_clave    (+)= hifl_fluj_clave \n"
                + "AND    fapr_hifl_numero   (+)= hifl_numero \n"
                + " " + condicion
                + " ORDER BY hifl_fluj_clave, hifl_numero DESC";
        return select(1);//1 es el numero de objeto para factura
    }
}
